package org.example.compare.schedule;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.example.compare.dto.*;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 新的测试数据生成器类，用于为calculateItem_3函数生成测试数据
 * 该函数使用到的非函数参数列表外部变量包括:
 * 1. SchData.hRate - 效率集合，以工序Id为索引的到向量，向量内部以效率从高到低进行排序
 * 2. SchData.pPositionDtos - 工位数据数组,按位置编号
 * 3. hProcessSet - 需要进行排产的工序集
 * 4. sPositionsScore - 可以排产的工位
 * 5. hScoreByProcess - 按工序查找的分数表
 */
public class CalculateItem3NewTestDataGenerator {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final Random random = new Random();

    static {
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 生成手动测试数据并保存到文件 - 案例1：正常流程
     */
    public static void generateManualTestCase1() throws IOException {
        String basePath = "../../test_data/calculateItem_3_new/manual_case_1";
        File baseDir = new File(basePath);

        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        // 创建测试用的工人技能效率数据
        Map<Long, List<WorkerTech>> hRate = new HashMap<>();

        // 工序1的效率数据 - 3个工人，效率不同
        List<WorkerTech> workerTechList1 = new ArrayList<>();
        
        WorkerTech workerTech1_1 = new WorkerTech();
        workerTech1_1.setWorkerTechId(1001L);
        workerTech1_1.setWorkerId(2001L);
        workerTech1_1.setProcessId(101L);
        workerTech1_1.setAvgProcessRate(95.5);
        workerTechList1.add(workerTech1_1);

        WorkerTech workerTech1_2 = new WorkerTech();
        workerTech1_2.setWorkerTechId(1002L);
        workerTech1_2.setWorkerId(2002L);
        workerTech1_2.setProcessId(101L);
        workerTech1_2.setAvgProcessRate(87.2);
        workerTechList1.add(workerTech1_2);

        WorkerTech workerTech1_3 = new WorkerTech();
        workerTech1_3.setWorkerTechId(1003L);
        workerTech1_3.setWorkerId(2003L);
        workerTech1_3.setProcessId(101L);
        workerTech1_3.setAvgProcessRate(75.8);
        workerTechList1.add(workerTech1_3);

        hRate.put(101L, workerTechList1);

        // 工序2的效率数据 - 2个工人
        List<WorkerTech> workerTechList2 = new ArrayList<>();
        
        WorkerTech workerTech2_1 = new WorkerTech();
        workerTech2_1.setWorkerTechId(1004L);
        workerTech2_1.setWorkerId(2004L);
        workerTech2_1.setProcessId(102L);
        workerTech2_1.setAvgProcessRate(92.0);
        workerTechList2.add(workerTech2_1);

        WorkerTech workerTech2_2 = new WorkerTech();
        workerTech2_2.setWorkerTechId(1005L);
        workerTech2_2.setWorkerId(2005L);
        workerTech2_2.setProcessId(102L);
        workerTech2_2.setAvgProcessRate(78.5);
        workerTechList2.add(workerTech2_2);

        hRate.put(102L, workerTechList2);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hRate.json"), hRate);

        // 生成工位数据
        Map<Long, PositionDto> pPositionDtos = new HashMap<>();

        // 工位1
        PositionDto position1 = new PositionDto();
        position1.setPositionId(3001L);
        position1.setWorkerId(2001L);
        position1.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(3001L, position1);

        // 工位2
        PositionDto position2 = new PositionDto();
        position2.setPositionId(3002L);
        position2.setWorkerId(2002L);
        position2.setMiPosStatus(2); // 仅在产
        pPositionDtos.put(3002L, position2);

        // 工位3
        PositionDto position3 = new PositionDto();
        position3.setPositionId(3003L);
        position3.setWorkerId(2003L);
        position3.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(3003L, position3);

        // 工位4
        PositionDto position4 = new PositionDto();
        position4.setPositionId(3004L);
        position4.setWorkerId(2004L);
        position4.setMiPosStatus(4); // 忙碌
        pPositionDtos.put(3004L, position4);

        // 工位5
        PositionDto position5 = new PositionDto();
        position5.setPositionId(3005L);
        position5.setWorkerId(2005L);
        position5.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(3005L, position5);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/pPositionDtos.json"), pPositionDtos);

        // 生成工序集数据
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 创建测试用的订单数据
        OrderDto orderDto = new OrderDto();
        orderDto.setMLocalOrderNum("TEST2023001");
        orderDto.setMiTotalPlanCnt(1000);

        // 工序1
        OrderProcess process1 = OrderProcess.InitOrderProcess(orderDto);
        process1.setProcessId(101L);
        process1.setOrderProcessId(101L);
        process1.setMfProcessTotalTime(120.0f); // 2分钟标准工时
        process1.setMiFinishedCnt(200);
        process1.setMiPartSeqNum(1);
        process1.setMPartId(100L);

        ProcessSch scheduling1 = new ProcessSch();
        scheduling1.setMbHoldFlag(false);
        scheduling1.setMbNGFlag(false);
        Set<Long> posCanDo1 = new HashSet<>();
        posCanDo1.add(3001L);
        posCanDo1.add(3002L);
        posCanDo1.add(3003L);
        scheduling1.setMPosCanDo(posCanDo1);

        process1.setMScheduling(scheduling1);
        hProcessSet.put(101L, process1);

        // 工序2
        OrderProcess process2 = OrderProcess.InitOrderProcess(orderDto);
        process2.setProcessId(102L);
        process2.setOrderProcessId(102L);
        process2.setMfProcessTotalTime(180.0f); // 3分钟标准工时
        process2.setMiFinishedCnt(150);
        process2.setMiPartSeqNum(2);
        process2.setMPartId(100L);

        ProcessSch scheduling2 = new ProcessSch();
        scheduling2.setMbHoldFlag(false);
        scheduling2.setMbNGFlag(false);
        Set<Long> posCanDo2 = new HashSet<>();
        posCanDo2.add(3004L);
        posCanDo2.add(3005L);
        scheduling2.setMPosCanDo(posCanDo2);

        process2.setMScheduling(scheduling2);
        hProcessSet.put(102L, process2);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        // 生成可以排产的工位数据
        Set<Long> sPositionsScore = new HashSet<>();
        sPositionsScore.add(3001L);
        sPositionsScore.add(3002L);
        sPositionsScore.add(3003L);
        sPositionsScore.add(3004L);
        sPositionsScore.add(3005L);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        // 生成按工序查找的分数表数据
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 工序1的分数
        List<Score> scores1 = new ArrayList<>();
        Score score1_1 = new Score();
        score1_1.setPositionId(3001L);
        score1_1.setTotal(80.0);
        double[] scoreItems1 = new double[20];
        for (int i = 0; i < scoreItems1.length; i++) {
            scoreItems1[i] = 5.0;
        }
        score1_1.setScoreItem(scoreItems1);
        scores1.add(score1_1);

        Score score1_2 = new Score();
        score1_2.setPositionId(3002L);
        score1_2.setTotal(75.0);
        double[] scoreItems2 = new double[20];
        for (int i = 0; i < scoreItems2.length; i++) {
            scoreItems2[i] = 4.5;
        }
        score1_2.setScoreItem(scoreItems2);
        scores1.add(score1_2);

        Score score1_3 = new Score();
        score1_3.setPositionId(3003L);
        score1_3.setTotal(70.0);
        double[] scoreItems3 = new double[20];
        for (int i = 0; i < scoreItems3.length; i++) {
            scoreItems3[i] = 4.0;
        }
        score1_3.setScoreItem(scoreItems3);
        scores1.add(score1_3);

        hScoreByProcess.put(101L, scores1);

        // 工序2的分数
        List<Score> scores2 = new ArrayList<>();
        Score score2_1 = new Score();
        score2_1.setPositionId(3004L);
        score2_1.setTotal(85.0);
        double[] scoreItems4 = new double[20];
        for (int i = 0; i < scoreItems4.length; i++) {
            scoreItems4[i] = 6.0;
        }
        score2_1.setScoreItem(scoreItems4);
        scores2.add(score2_1);

        Score score2_2 = new Score();
        score2_2.setPositionId(3005L);
        score2_2.setTotal(70.0);
        double[] scoreItems5 = new double[20];
        for (int i = 0; i < scoreItems5.length; i++) {
            scoreItems5[i] = 4.0;
        }
        score2_2.setScoreItem(scoreItems5);
        scores2.add(score2_2);

        hScoreByProcess.put(102L, scores2);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);

        // 生成函数参数
        Map<String, Object> functionParams = new HashMap<>();
        functionParams.put("ratio", 0.1);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);
    }

    /**
     * 生成手动测试数据并保存到文件 - 案例2：包含特殊情况
     */
    public static void generateManualTestCase2() throws IOException {
        String basePath = "../../test_data/calculateItem_3_new/manual_case_2";
        File baseDir = new File(basePath);

        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        // 创建测试用的工人技能效率数据
        Map<Long, List<WorkerTech>> hRate = new HashMap<>();

        // 工序1的效率数据 - 所有工人效率相同
        List<WorkerTech> workerTechList1 = new ArrayList<>();
        
        WorkerTech workerTech1_1 = new WorkerTech();
        workerTech1_1.setWorkerTechId(2001L);
        workerTech1_1.setWorkerId(3001L);
        workerTech1_1.setProcessId(201L);
        workerTech1_1.setAvgProcessRate(85.0);
        workerTechList1.add(workerTech1_1);

        WorkerTech workerTech1_2 = new WorkerTech();
        workerTech1_2.setWorkerTechId(2002L);
        workerTech1_2.setWorkerId(3002L);
        workerTech1_2.setProcessId(201L);
        workerTech1_2.setAvgProcessRate(85.0);
        workerTechList1.add(workerTech1_2);

        hRate.put(201L, workerTechList1);

        // 工序2的效率数据 - 正常情况
        List<WorkerTech> workerTechList2 = new ArrayList<>();
        
        WorkerTech workerTech2_1 = new WorkerTech();
        workerTech2_1.setWorkerTechId(2003L);
        workerTech2_1.setWorkerId(3003L);
        workerTech2_1.setProcessId(202L);
        workerTech2_1.setAvgProcessRate(95.0);
        workerTechList2.add(workerTech2_1);

        WorkerTech workerTech2_2 = new WorkerTech();
        workerTech2_2.setWorkerTechId(2004L);
        workerTech2_2.setWorkerId(3004L);
        workerTech2_2.setProcessId(202L);
        workerTech2_2.setAvgProcessRate(80.0);
        workerTechList2.add(workerTech2_2);

        hRate.put(202L, workerTechList2);

        // 工序3的效率数据 - 单个工人
        List<WorkerTech> workerTechList3 = new ArrayList<>();
        
        WorkerTech workerTech3_1 = new WorkerTech();
        workerTech3_1.setWorkerTechId(2005L);
        workerTech3_1.setWorkerId(3005L);
        workerTech3_1.setProcessId(203L);
        workerTech3_1.setAvgProcessRate(90.0);
        workerTechList3.add(workerTech3_1);

        hRate.put(203L, workerTechList3);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hRate.json"), hRate);

        // 生成工位数据
        Map<Long, PositionDto> pPositionDtos = new HashMap<>();

        // 工位1
        PositionDto position1 = new PositionDto();
        position1.setPositionId(4001L);
        position1.setWorkerId(3001L);
        position1.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(4001L, position1);

        // 工位2
        PositionDto position2 = new PositionDto();
        position2.setPositionId(4002L);
        position2.setWorkerId(3002L);
        position2.setMiPosStatus(2); // 仅在产
        pPositionDtos.put(4002L, position2);

        // 工位3
        PositionDto position3 = new PositionDto();
        position3.setPositionId(4003L);
        position3.setWorkerId(3003L);
        position3.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(4003L, position3);

        // 工位4
        PositionDto position4 = new PositionDto();
        position4.setPositionId(4004L);
        position4.setWorkerId(3004L);
        position4.setMiPosStatus(4); // 忙碌
        pPositionDtos.put(4004L, position4);

        // 工位5
        PositionDto position5 = new PositionDto();
        position5.setPositionId(4005L);
        position5.setWorkerId(3005L);
        position5.setMiPosStatus(1); // 空闲状态
        pPositionDtos.put(4005L, position5);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/pPositionDtos.json"), pPositionDtos);

        // 生成工序集数据
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 创建测试用的订单数据
        OrderDto orderDto = new OrderDto();
        orderDto.setMLocalOrderNum("TEST2023002");
        orderDto.setMiTotalPlanCnt(800);

        // 工序1 (挂起状态)
        OrderProcess process1 = OrderProcess.InitOrderProcess(orderDto);
        process1.setProcessId(201L);
        process1.setOrderProcessId(201L);
        process1.setMfProcessTotalTime(90.0f); // 1.5分钟标准工时
        process1.setMiFinishedCnt(100);
        process1.setMiPartSeqNum(1);
        process1.setMPartId(200L);

        ProcessSch scheduling1 = new ProcessSch();
        scheduling1.setMbHoldFlag(true); // 挂起状态
        scheduling1.setMbNGFlag(false);
        Set<Long> posCanDo1 = new HashSet<>();
        posCanDo1.add(4001L);
        posCanDo1.add(4002L);
        scheduling1.setMPosCanDo(posCanDo1);

        process1.setMScheduling(scheduling1);
        hProcessSet.put(201L, process1);

        // 工序2 (NG状态)
        OrderProcess process2 = OrderProcess.InitOrderProcess(orderDto);
        process2.setProcessId(202L);
        process2.setOrderProcessId(202L);
        process2.setMfProcessTotalTime(150.0f); // 2.5分钟标准工时
        process2.setMiFinishedCnt(50);
        process2.setMiPartSeqNum(2);
        process2.setMPartId(200L);

        ProcessSch scheduling2 = new ProcessSch();
        scheduling2.setMbHoldFlag(false);
        scheduling2.setMbNGFlag(true); // NG状态
        Set<Long> posCanDo2 = new HashSet<>();
        posCanDo2.add(4003L);
        posCanDo2.add(4004L);
        scheduling2.setMPosCanDo(posCanDo2);

        process2.setMScheduling(scheduling2);
        hProcessSet.put(202L, process2);

        // 工序3 (正常状态)
        OrderProcess process3 = OrderProcess.InitOrderProcess(orderDto);
        process3.setProcessId(203L);
        process3.setOrderProcessId(203L);
        process3.setMfProcessTotalTime(200.0f); // 约3.3分钟标准工时
        process3.setMiFinishedCnt(75);
        process3.setMiPartSeqNum(3);
        process3.setMPartId(200L);

        ProcessSch scheduling3 = new ProcessSch();
        scheduling3.setMbHoldFlag(false);
        scheduling3.setMbNGFlag(false);
        Set<Long> posCanDo3 = new HashSet<>();
        posCanDo3.add(4005L);
        scheduling3.setMPosCanDo(posCanDo3);

        process3.setMScheduling(scheduling3);
        hProcessSet.put(203L, process3);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        // 生成可以排产的工位数据
        Set<Long> sPositionsScore = new HashSet<>();
        sPositionsScore.add(4001L);
        sPositionsScore.add(4002L);
        sPositionsScore.add(4003L);
        sPositionsScore.add(4004L);
        sPositionsScore.add(4005L);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        // 生成按工序查找的分数表数据
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 工序1的分数 (挂起状态)
        List<Score> scores1 = new ArrayList<>();
        Score score1_1 = new Score();
        score1_1.setPositionId(4001L);
        score1_1.setTotal(90.0);
        double[] scoreItems1 = new double[20];
        for (int i = 0; i < scoreItems1.length; i++) {
            scoreItems1[i] = 7.0;
        }
        score1_1.setScoreItem(scoreItems1);
        scores1.add(score1_1);

        Score score1_2 = new Score();
        score1_2.setPositionId(4002L);
        score1_2.setTotal(85.0);
        double[] scoreItems2 = new double[20];
        for (int i = 0; i < scoreItems2.length; i++) {
            scoreItems2[i] = 6.5;
        }
        score1_2.setScoreItem(scoreItems2);
        scores1.add(score1_2);

        hScoreByProcess.put(201L, scores1);

        // 工序2的分数 (NG状态)
        List<Score> scores2 = new ArrayList<>();
        Score score2_1 = new Score();
        score2_1.setPositionId(4003L);
        score2_1.setTotal(80.0);
        double[] scoreItems3 = new double[20];
        for (int i = 0; i < scoreItems3.length; i++) {
            scoreItems3[i] = 5.0;
        }
        score2_1.setScoreItem(scoreItems3);
        scores2.add(score2_1);

        Score score2_2 = new Score();
        score2_2.setPositionId(4004L);
        score2_2.setTotal(75.0);
        double[] scoreItems4 = new double[20];
        for (int i = 0; i < scoreItems4.length; i++) {
            scoreItems4[i] = 4.5;
        }
        score2_2.setScoreItem(scoreItems4);
        scores2.add(score2_2);

        hScoreByProcess.put(202L, scores2);

        // 工序3的分数 (正常状态)
        List<Score> scores3 = new ArrayList<>();
        Score score3_1 = new Score();
        score3_1.setPositionId(4005L);
        score3_1.setTotal(95.0);
        double[] scoreItems5 = new double[20];
        for (int i = 0; i < scoreItems5.length; i++) {
            scoreItems5[i] = 8.0;
        }
        score3_1.setScoreItem(scoreItems5);
        scores3.add(score3_1);

        hScoreByProcess.put(203L, scores3);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);

        Map<String, Object> functionParams = new HashMap<>();
        functionParams.put("ratio", 0.15);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);
    }

    /**
     * 生成随机测试数据并保存到文件
     */
    public static void generateRandomTestData(int iteration) throws IOException {
        String basePath = "../../test_data/calculateItem_3_new/random_case_" + iteration;
        File baseDir = new File(basePath);

        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        // 生成测试数据 - 注意顺序很重要
        Map<Long, List<WorkerTech>> hRate = generateWorkerTechData(basePath);
        Map<Long, PositionDto> pPositionDtos = generatePositionDtoData(basePath);
        Map<Long, OrderProcess> hProcessSet = generateProcessSetData(basePath, hRate);
        Set<Long> sPositionsScore = generatePositionScoreData(basePath, pPositionDtos);
        generateScoreByProcessData(basePath, hProcessSet, sPositionsScore, hRate, pPositionDtos);
        generateFunctionParams(basePath);
    }

    /**
     * 生成工人技能效率数据
     */
    private static Map<Long, List<WorkerTech>> generateWorkerTechData(String basePath) throws IOException {
        Map<Long, List<WorkerTech>> hRate = new HashMap<>();

        // 随机生成工序数量 3-8个
        int processCount = 3 + random.nextInt(6);

        List<Long> processIds = new ArrayList<>();
        for (int i = 0; i < processCount; i++) {
            processIds.add(1000L + i * 10 + random.nextInt(10));
        }

        for (Long processId : processIds) {
            List<WorkerTech> workerTechList = new ArrayList<>();

            // 每个工序对应1-5个工人技能数据
            int workerCount = 1 + random.nextInt(5);
            for (int j = 0; j < workerCount; j++) {
                WorkerTech workerTech = new WorkerTech();
                workerTech.setWorkerTechId(10000L + processId * 100 + j);
                workerTech.setWorkerId(20000L + processId * 100 + j);
                workerTech.setProcessId(processId);
                // 效率值保留两位小数
                double avgProcessRate = 50.0 + random.nextDouble() * 50.0; // 50-100的效率值
                avgProcessRate = new BigDecimal(avgProcessRate).setScale(2, RoundingMode.HALF_UP).doubleValue();
                workerTech.setAvgProcessRate(avgProcessRate);
                workerTechList.add(workerTech);
            }

            hRate.put(processId, workerTechList);
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hRate.json"), hRate);

        return hRate;
    }

    /**
     * 生成工位数据
     */
    private static Map<Long, PositionDto> generatePositionDtoData(String basePath) throws IOException {
        Map<Long, PositionDto> pPositionDtos = new HashMap<>();

        // 随机生成工位数量 5-15个
        int positionCount = 5 + random.nextInt(11);

        for (int i = 0; i < positionCount; i++) {
            PositionDto position = new PositionDto();
            long positionId = 10000L + random.nextInt(90000); // 10000-99999的工位ID
            position.setPositionId(positionId);
            position.setWorkerId(20000L + i); // 关联的工人ID
            position.setMiPosStatus(random.nextInt(7)); // 0-6的工位状态
            pPositionDtos.put(positionId, position);
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/pPositionDtos.json"), pPositionDtos);

        return pPositionDtos;
    }

    /**
     * 生成工序集数据
     */
    private static Map<Long, OrderProcess> generateProcessSetData(String basePath,
                                                                 Map<Long, List<WorkerTech>> hRate) throws IOException {
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 使用hRate中的工序ID来确保一致性
        List<Long> processIds = new ArrayList<>(hRate.keySet());

        // 创建测试用的订单数据
        OrderDto orderDto = new OrderDto();
        orderDto.setMLocalOrderNum("TEST" + (3000 + random.nextInt(100)) + "" + (100000 + random.nextInt(900000)));
        orderDto.setMiTotalPlanCnt(500 + random.nextInt(1001)); // 500-1500

        for (Long processId : processIds) {
            OrderProcess process = OrderProcess.InitOrderProcess(orderDto);
            process.setProcessId(processId);
            process.setOrderProcessId(processId);
            // 标准工时保留两位小数
            float processTime = 60.0f + random.nextInt(600);
            processTime = new BigDecimal(processTime).setScale(2, RoundingMode.HALF_UP).floatValue();
            process.setMfProcessTotalTime(processTime); // 60-660秒标准工时
            process.setMiFinishedCnt(random.nextInt(orderDto.getMiTotalPlanCnt()));
            process.setMiPartSeqNum(processIds.indexOf(processId) + 1);
            process.setMPartId((long) (100 + random.nextInt(5))); // 100-104部件ID

            ProcessSch scheduling = new ProcessSch();
            // 20%概率设置为挂起状态
            scheduling.setMbHoldFlag(random.nextDouble() < 0.2);
            // 10%概率设置为NG状态
            scheduling.setMbNGFlag(random.nextDouble() < 0.1);

            // 设置可以做的工位集合，从hRate中获取相关工人的工位信息
            Set<Long> posCanDo = new HashSet<>();
            List<WorkerTech> workerTechList = hRate.get(processId);
            if (workerTechList != null) {
                // 为每个工人关联的工位添加到可做工位集合中
                for (WorkerTech workerTech : workerTechList) {
                    // 我们需要找到与这个工人关联的工位
                    // 在实际应用中，这会通过数据库或其他方式关联
                    // 在测试数据中，我们使用基于工人ID的工位ID
                    posCanDo.add(10000L + workerTech.getWorkerId() % 90000);
                }
            }
            scheduling.setMPosCanDo(posCanDo);

            process.setMScheduling(scheduling);
            hProcessSet.put(processId, process);
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        return hProcessSet;
    }

    /**
     * 生成可以排产的工位数据
     */
    private static Set<Long> generatePositionScoreData(String basePath,
                                                      Map<Long, PositionDto> pPositionDtos) throws IOException {
        Set<Long> sPositionsScore = new HashSet<>();

        // 使用实际存在的工位ID，而不是随机生成
        sPositionsScore.addAll(pPositionDtos.keySet());

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        return sPositionsScore;
    }

    /**
     * 生成按工序查找的分数表数据
     */
    private static void generateScoreByProcessData(String basePath, Map<Long, OrderProcess> hProcessSet,
                                                   Set<Long> sPositionsScore, Map<Long, List<WorkerTech>> hRate,
                                                   Map<Long, PositionDto> pPositionDtos) throws IOException {
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 使用已生成的工序ID来创建分数数据
        List<Long> processIds = new ArrayList<>(hProcessSet.keySet());

        for (Long processId : processIds) {
            List<Score> scores = new ArrayList<>();

            // 获取部分工位ID用于这个工序
            List<Long> positionIds = new ArrayList<>(sPositionsScore);
            Collections.shuffle(positionIds); // 随机打乱

            // 每个工序对应1-5个工位分数（不超过工位总数）
            int scoreCount = Math.min(1 + random.nextInt(5), positionIds.size());
            for (int j = 0; j < scoreCount; j++) {
                Score score = new Score();
                score.setPositionId(positionIds.get(j));
                // 总分保留两位小数
                double total = random.nextDouble() * 100; // 0-100的总分
                total = new BigDecimal(total).setScale(2, RoundingMode.HALF_UP).doubleValue();
                score.setTotal(total);

                // 初始化分数项数组，包含随机分数，每项保留两位小数
                double[] scoreItems = new double[20];
                for (int k = 0; k < scoreItems.length; k++) {
                    double item = random.nextDouble() * 50; // 0-50的分数项
                    item = new BigDecimal(item).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    scoreItems[k] = item;
                }
                score.setScoreItem(scoreItems);

                scores.add(score);
            }

            hScoreByProcess.put(processId, scores);
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);
    }

    /**
     * 生成函数参数
     */
    private static void generateFunctionParams(String basePath) throws IOException {
        Map<String, Object> functionParams = new HashMap<>();
        // 生成 0.01 到 1.0 之间的随机 ratio 值，保留两位小数
        double randomRatio = 0.01 + random.nextDouble() * 0.99;
        randomRatio = new BigDecimal(randomRatio).setScale(2, RoundingMode.HALF_UP).doubleValue();
        functionParams.put("ratio", randomRatio);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);
    }

    public static void main(String[] args) {
        try {
            // 确保主目录存在
            File mainDir = new File("../../test_data/calculateItem_3_new");
            if (!mainDir.exists()) {
                mainDir.mkdirs();
            }

            // 生成2个手动测试案例
            generateManualTestCase1();
            System.out.println("手动测试案例 1 已成功生成");

            generateManualTestCase2();
            System.out.println("手动测试案例 2 已成功生成");

            // 生成50组随机测试数据
            for (int i = 1; i <= 50; i++) {
                generateRandomTestData(i);
                System.out.println("随机测试数据集 " + i + " 已成功生成");
            }

            System.out.println("所有测试数据已成功生成并保存到../../test_data/calculateItem_3_new目录下");
        } catch (IOException e) {
            System.err.println("生成测试数据时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}